/**
 * WangEditor错误处理工具函数
 * 主要用于处理Slate编辑器与Markdown内容之间的冲突
 */

/**
 * 清理HTML内容，移除可能导致Slate编辑器冲突的元素和属性
 * @param html HTML字符串
 * @returns 清理后的HTML字符串
 */
export function cleanHtmlForSlateEditor(html: string): string {
  if (!html || typeof html !== 'string') return '<p><br></p>';

  try {
    // 创建临时DOM元素来清理HTML
    const tempDiv = document.createElement('div');
    tempDiv.innerHTML = html;

    // 移除可能导致冲突的属性和元素
    const elementsToClean = tempDiv.querySelectorAll('*');
    elementsToClean.forEach(el => {
      // 移除Slate相关的属性
      const attributesToRemove = [
        'data-slate-node',
        'data-slate-inline',
        'data-slate-void',
        'data-slate-leaf',
        'data-slate-string',
        'data-slate-zero-width',
        'data-slate-editor',
        'data-slate-fragment',
        'data-key',
        'contenteditable',
        'data-w-e-type',
        'data-w-e-is-void',
        'data-w-e-is-inline',
        'spellcheck',
        'autocorrect',
        'autocapitalize',
        'translate'
      ];

      attributesToRemove.forEach(attr => {
        if (el.hasAttribute(attr)) {
          el.removeAttribute(attr);
        }
      });

      // 移除所有以data-slate-开头的属性
      Array.from(el.attributes).forEach(attr => {
        if (attr.name.startsWith('data-slate-') ||
            attr.name.startsWith('data-w-e-') ||
            attr.name.startsWith('data-testid') ||
            attr.name.includes('slate')) {
          el.removeAttribute(attr.name);
        }
      });

      // 移除空的span元素（这些经常导致Slate错误）
      if (el.tagName.toLowerCase() === 'span' &&
          !el.textContent?.trim() &&
          !el.querySelector('img, br, hr')) {
        el.remove();
      }

      // 确保所有文本节点都在合适的容器中
      if (el.tagName.toLowerCase() === 'div' && !el.children.length && el.textContent?.trim()) {
        const p = document.createElement('p');
        p.textContent = el.textContent;
        el.parentNode?.replaceChild(p, el);
      }
    });

    // 确保内容不为空
    const cleanedContent = tempDiv.innerHTML.trim();
    if (!cleanedContent || cleanedContent === '<br>' || cleanedContent === '<p></p>') {
      return '<p><br></p>';
    }

    return cleanedContent;
  } catch (error) {
    // console.warn('清理HTML内容时出错:', error);
    return '<p><br></p>';
  }
}

/**
 * 使用正则表达式清理HTML内容（备用方法）
 * @param html HTML字符串
 * @returns 清理后的HTML字符串
 */
export function cleanHtmlWithRegex(html: string): string {
  if (!html || typeof html !== 'string') return '';
  
  try {
    return html
      // 移除data-slate-*属性
      .replace(/\s*data-slate-[^=]*="[^"]*"/g, '')
      // 移除data-key属性
      .replace(/\s*data-key="[^"]*"/g, '')
      // 移除contenteditable属性
      .replace(/\s*contenteditable="[^"]*"/g, '')
      // 移除wangEditor相关属性
      .replace(/\s*data-w-e-[^=]*="[^"]*"/g, '')
      // 清理多余的空格
      .replace(/\s+/g, ' ')
      .trim();
  } catch (error) {
    // console.warn('使用正则表达式清理HTML内容时出错:', error);
    return html;
  }
}

/**
 * 安全地设置编辑器内容
 * @param editor WangEditor实例
 * @param content 要设置的内容
 * @param maxRetries 最大重试次数
 */
export function safeSetEditorContent(
  editor: any,
  content: string,
  maxRetries: number = 3
): Promise<void> {
  return new Promise((resolve, reject) => {
    let retryCount = 0;

    const attemptSet = () => {
      try {
        if (!editor) {
          reject(new Error('编辑器实例不存在'));
          return;
        }

        // 先清理内容
        const cleanedContent = cleanHtmlForSlateEditor(content);
        // console.log('尝试设置编辑器内容:', cleanedContent);

        // 使用更安全的方式设置内容
        setTimeout(() => {
          try {
            // 先清空编辑器
            editor.clear();

            // 等待一个tick后设置内容
            setTimeout(() => {
              try {
                if (cleanedContent && cleanedContent !== '<p><br></p>') {
                  editor.setHtml(cleanedContent);
                } else {
                  editor.setHtml('<p><br></p>');
                }
                resolve();
              } catch (setError) {
                // console.warn('设置HTML失败，尝试使用dangerouslyInsertHtml:', setError);
                try {
                  editor.dangerouslyInsertHtml(cleanedContent);
                  resolve();
                } catch (insertError) {
                  // throw insertError;
                }
              }
            }, 50);
          } catch (error) {
            throw error;
          }
        }, 10);

      } catch (error) {
        retryCount++;
        // console.warn(`设置编辑器内容失败，第${retryCount}次重试:`, error);

        if (retryCount < maxRetries) {
          // 延迟重试
          setTimeout(() => {
            attemptSet();
          }, 200 * retryCount);
        } else {
          // console.error('设置编辑器内容最终失败:', error);
          // 最后尝试设置为空内容
          try {
            editor.clear();
            setTimeout(() => {
              editor.setHtml('<p><br></p>');
              resolve();
            }, 100);
          } catch (finalError) {
            reject(finalError);
          }
        }
      }
    };

    attemptSet();
  });
}

/**
 * 检查是否为Slate相关错误
 * @param error 错误对象
 * @returns 是否为Slate相关错误
 */
export function isSlateError(error: any): boolean {
  if (!error) return false;

  const errorMessage = error.message || error.toString();
  const slateErrorPatterns = [
    'Cannot resolve a Slate node from DOM node',
    'Cannot find a descendant at path',
    'Cannot get the leaf node at path',
    'Cannot get the parent of path',
    'Cannot get the start point of range',
    'Cannot get the end point of range',
    'slate-react',
    'toSlateNode',
    'toSlatePoint',
    'toSlateRange'
  ];

  return slateErrorPatterns.some(pattern =>
    errorMessage.toLowerCase().includes(pattern.toLowerCase())
  );
}

/**
 * 处理Slate错误的专用函数
 * @param editor WangEditor实例
 * @param error 错误对象
 * @returns Promise<boolean> 是否成功恢复
 */
export async function handleSlateError(editor: any, error: any): Promise<boolean> {
  if (!isSlateError(error)) {
    return false;
  }

  // console.warn('检测到Slate错误，开始恢复流程:', error.message);

  try {
    // 方法1: 清空编辑器并重新设置基本内容
    await new Promise<void>((resolve, reject) => {
      try {
        editor.clear();
        setTimeout(() => {
          try {
            editor.setHtml('<p><br></p>');
            resolve();
          } catch (setError) {
            reject(setError);
          }
        }, 100);
      } catch (clearError) {
        reject(clearError);
      }
    });

    // console.log('Slate错误恢复成功');
    return true;
  } catch (recoveryError) {
    // console.error('Slate错误恢复失败:', recoveryError);

    // 方法2: 尝试重新创建编辑器内容
    try {
      editor.dangerouslyInsertHtml('<p><br></p>');
      // console.log('使用备用方法恢复Slate错误成功');
      return true;
    } catch (fallbackError) {
      // console.error('备用恢复方法也失败:', fallbackError);
      return false;
    }
  }
}

/**
 * 处理编辑器错误的通用函数
 * @param error 错误对象
 * @param context 错误上下文信息
 */
export function handleEditorError(error: any, context: string = '编辑器操作'): void {
  if (isSlateError(error)) {
    // console.warn(`${context}中出现Slate编辑器错误:`, error.message);
    // 可以在这里添加用户友好的错误提示
  } else {
    // console.error(`${context}中出现未知错误:`, error);
  }
}

/**
 * 检查并修复编辑器高度，确保大于最小高度要求
 * @param editorContainer 编辑器容器元素
 * @param minHeight 最小高度（默认350px）
 */
export function checkAndFixEditorHeight(
  editorContainer: HTMLElement | null,
  minHeight: number = 350
): void {
  if (!editorContainer) {
    // console.warn('编辑器容器不存在，无法检查高度');
    return;
  }

  try {
    // 检查文本容器高度
    const textContainer = editorContainer.querySelector('.w-e-text-container') as HTMLElement;
    if (textContainer) {
      const currentHeight = textContainer.offsetHeight;
      if (currentHeight < minHeight) {
        // console.warn(`编辑器文本容器高度 ${currentHeight}px < ${minHeight}px，正在修复...`);
        textContainer.style.height = `${minHeight}px`;
        textContainer.style.minHeight = `${minHeight}px`;
      }
    }

    // 检查滚动容器高度
    const scrollContainer = editorContainer.querySelector('.w-e-text-container .w-e-scroll') as HTMLElement;
    if (scrollContainer) {
      const currentHeight = scrollContainer.offsetHeight;
      if (currentHeight < minHeight) {
        // console.warn(`编辑器滚动容器高度 ${currentHeight}px < ${minHeight}px，正在修复...`);
        scrollContainer.style.height = 'auto';
        scrollContainer.style.minHeight = `${minHeight}px`;
      }
    }

    // 检查编辑器容器本身的高度
    const containerHeight = editorContainer.offsetHeight;
    if (containerHeight < minHeight) {
      // console.warn(`编辑器容器高度 ${containerHeight}px < ${minHeight}px，正在修复...`);
      editorContainer.style.minHeight = `${minHeight}px`;
    }
  } catch (error) {
    // console.error('检查编辑器高度时出错:', error);
  }
}
